package com.ruoyi.web.controller.api;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.RechargeUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.SysChannel;
import com.ruoyi.system.domain.SysOrder;
import com.ruoyi.system.domain.SysStore;
import com.ruoyi.system.mapper.SysChannelMapper;
import com.ruoyi.system.service.ISysChannelService;
import com.ruoyi.system.service.ISysOrderService;
import com.ruoyi.system.service.ISysStoreService;
import com.ruoyi.web.controller.utils.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.*;

/**
 * 充值 Controller
 * 
 * @author ruoyi
 * @date 2022-01-17
 */
@RestController
@RequestMapping("/api/recharge")
public class RechargeApiController extends BaseController
{

    public static Logger logger = LoggerFactory.getLogger(RechargeApiController.class);

    @Autowired
    private SysOrderService myOrderService;
    @Autowired
    private ISysOrderService sysOrderService;
    @Autowired
    private SysChannelMapper sysChannelMapper;
    @Autowired
    private ISysChannelService sysChannelService;

    @Autowired
    private ISysStoreService sysStoreService;

    @Log(title = "充值", businessType = BusinessType.RECHARGE)
    @PostMapping("/doRecharge")
    public JR recharge(@RequestBody StoreRechargeDTO dto) {
        if(dto == null || StrUtil.isEmpty(dto.getStoreCode()) ||StrUtil.isEmpty(dto.getCreateTime()) ||StrUtil.isEmpty(dto.getSign())||dto.getChildList() == null || dto.getChildList().size() ==0){
            return JR.build(500,"参数为空，请求失败",500);
        }
        if(CollectionUtils.isEmpty(dto.getChildList())){
            return JR.build(500,"充值信息为空",500);
        }
        if(dto.getChildList().size()>100){
            return JR.build(500,"目前系统只支持批量处理100条",500);
        }
        try{
            JR jr = myOrderService.storeRecharge(dto);
            return jr;
        }catch (Exception e){
            logger.info("doRecharge error:"+e.getMessage());
            return JR.build(500,"充值失败",500);
        }

    }

    @Log(title = "渠道回调A = 深圳盈华", businessType = BusinessType.YHCALLBACK)
    @PostMapping("/yhCallback")
    public JR channelCallbackA(HttpServletRequest request)
    {
        logger.info("盈华回调开始<<<<<<<<<<");
        Map<String, String[]> mapparams = request.getParameterMap();
        //logger.info("盈华回调 mapparams:"+JsonUtils.objectToJson(mapparams));
        Set<String> keySet = mapparams.keySet();
        Iterator<String> it = keySet.iterator();
        String next = "";
        while (it.hasNext()) {
            next =it.next();
          if(!StringUtils.isEmpty(next)){
              logger.info("盈华回调 next:"+next);
              break;
          }
        }
        Map paramMap  = JsonUtils.jsonToPojo(next,Map.class);
        String code= "";
        String msg = "";
        String data = "";
       try{
           if(paramMap == null){
               logger.info("盈华回调参数转map失败");
               return JR.build(500,"回调参数解析失败",500);
           }
           if(paramMap.get("code") == null || paramMap.get("data") == null){
               logger.info("盈华回调参数里code和data缺失");
               return JR.build(500,"回调参数code和data缺失",500);
           }
           code = String.valueOf(paramMap.get("code"));
           msg = paramMap.get("msg")!= null ? String.valueOf(paramMap.get("msg")) :"";
           data = JsonUtils.objectToJson(paramMap.get("data"));
       }catch (Exception exception){
           logger.info("解析盈华回调函数的入参失败："+exception);
           return JR.build(500,"解析回调函数入参异常",500);
       }
        logger.info("渠道回调-盈华，code:"+code+",data:"+data+",msg:"+msg);
        if(StringUtils.isEmpty(code) || StringUtils.isEmpty(data)){
            logger.info("盈华回调参数为空");
            return JR.build(500,"盈华回调参数为空",500);
        }
        Map dataMap = JsonUtils.jsonToPojo(data,Map.class);
        if(dataMap == null || dataMap.get("spOrderID") == null || dataMap.get("orderID") == null){
            logger.info("盈华回调订单信息为空");
            return JR.build(500,"盈华回调订单信息为空",500);
        }
        SysOrder sysOrder = sysOrderService.getInfoBySysOrderNo(String.valueOf(dataMap.get("spOrderID")));
        if(sysOrder == null){
            logger.info("系统订单不存在，回调失败");
            return JR.build(500,"系统订单不存在，回调失败",500);
        }
        //告诉商家，充值成功
        SysStore sysStore = sysStoreService.checkStoreByCode(sysOrder.getStoreCode());
        if(sysOrder == null){
            logger.info("商户不存在，回调失败");
            return JR.build(500,"商户不存在，回调失败",500);
        }
        if("200".equals(code)){
            //修改SysOrder对象
            sysOrder.setSysOrderStatus(2); //充值成功
            sysOrder.setSysOrderStatusApi(1);
            sysOrder.setOrderFinishTime(new Date());
            sysOrder.setUpdateTime(new Date());
            sysOrder.setErrorMsg("");
            sysOrder.setChannelOrderNo(String.valueOf(dataMap.get("orderID")));
            Long time = DateUtils.getCurTimestamp().getTime()-sysOrder.getChannelStartTime().getTime();
            sysOrder.setChannelResultTime(time != null ? time/1000:0);
            //告诉商家，充值成功
            sysOrderService.updateSysOrder(sysOrder);
            if(sysStore != null){
                String storeCallBackStr = RechargeUtils.doStoreCallBack(sysStore.getCallBackUrl(),sysOrder.getStoreOrderNo(),sysOrder.getSysOrderNo(),"200",DateUtils.dateTimeNow("yyyyMMddHHmmss"),"");
                logger.info("商户回调结果："+storeCallBackStr);
            }
        }else{
            //失败
            SysChannel search = new SysChannel();
            search.setIsLock(0);
            List<SysChannel> channelList = sysChannelMapper.selectSysChannelList(search);
            SysChannel sysChannel = sysChannelService.getNextChannelObj(channelList,sysOrder);
            if(sysChannel == null){
                logger.info("没有可使用的渠道了，充值失败");
                sysOrder.setSysOrderStatus(4);
                sysOrder.setSysOrderStatusApi(2);
                sysOrder.setOrderFinishTime(new Date());
                sysOrder.setUpdateTime(new Date());
                Long time = DateUtils.getCurTimestamp().getTime()-sysOrder.getChannelStartTime().getTime();
                sysOrder.setChannelResultTime(time != null ? time/1000:0);
                sysOrderService.updateSysOrder(sysOrder);
                String storeCallBackStr =RechargeUtils.doStoreCallBack(sysStore.getCallBackUrl(),sysOrder.getStoreOrderNo(),sysOrder.getSysOrderNo(),"500",DateUtils.dateTimeNow("yyyyMMddHHmmss"),"充值失败");
                logger.info("商户回调结果："+storeCallBackStr);
            }else{
                sysOrderService.doRechargeChannel(sysChannel,sysOrder,sysStore);
            }
        }

        return JR.ok();
    }


    @Log(title = "渠道回调B-欧飞", businessType = BusinessType.OFCALLBACK)
    @PostMapping("/ofCallback")
    @ResponseBody
    public AjaxResult channelCallbackB(String ret_code,String sporder_id ,String ordersuccesstime ,String err_msg)
    {
        logger.info("渠道回调-欧飞，orderId:"+sporder_id+",code:"+ret_code+",time:"+ordersuccesstime+",errMsg:"+err_msg);

        if(StringUtils.isEmpty(ret_code) || StringUtils.isEmpty(sporder_id)){
            return toAjax(true);
        }
        SysOrder sysOrder = sysOrderService.getInfoBySysOrderNo(sporder_id);
        if(sysOrder == null){
            logger.info("系统订单不存在，回调失败");
            return toAjax(false);
        }
        //告诉商家，充值成功
        SysStore sysStore = sysStoreService.checkStoreByCode(sysOrder.getStoreCode());
        if("1".equals(ret_code)){
            //修改SysOrder对象
            sysOrder.setSysOrderStatus(2); //充值成功
            sysOrder.setSysOrderStatusApi(1);
            sysOrder.setOrderFinishTime(new Date());
            sysOrder.setUpdateTime(new Date());
            sysOrder.setErrorMsg("");
            Long time = DateUtils.getCurTimestamp().getTime()-sysOrder.getChannelStartTime().getTime();
            sysOrder.setChannelResultTime(time != null ? time/1000 : 0);
            sysOrderService.updateSysOrder(sysOrder);
            if(sysStore != null){
                String storeCallBackStr = RechargeUtils.doStoreCallBack(sysStore.getCallBackUrl(),sysOrder.getStoreOrderNo(),sysOrder.getSysOrderNo(),"200",ordersuccesstime,"");
                logger.info("商户回调结果："+storeCallBackStr);
            }
        }else{
            //失败
            SysChannel search = new SysChannel();
            search.setIsLock(0);
            List<SysChannel> channelList = sysChannelMapper.selectSysChannelList(search);
            SysChannel sysChannel = sysChannelService.getNextChannelObj(channelList,sysOrder);
            if(sysChannel == null){
                logger.info("没有可使用的渠道了，充值失败");
                // 1、订单充值失败，2、回调商家
                sysOrder.setSysOrderStatus(4);
                sysOrder.setSysOrderStatusApi(2);
                sysOrder.setOrderFinishTime(new Date());
                sysOrder.setUpdateTime(new Date());
                Long time = DateUtils.getCurTimestamp().getTime()-sysOrder.getChannelStartTime().getTime();
                sysOrder.setChannelResultTime(time != null ? time/1000 : 0);
                sysOrderService.updateSysOrder(sysOrder);
                //通知商户充值失败
                String storeCallBackStr = RechargeUtils.doStoreCallBack(sysStore.getCallBackUrl(),sysOrder.getStoreOrderNo(),sysOrder.getSysOrderNo(),"500",DateUtils.dateTimeNow("yyyyMMddHHmmss"),"充值失败");
                logger.info("商户回调结果："+storeCallBackStr);
            }else{
                sysOrderService.doRechargeChannel(sysChannel,sysOrder,sysStore);
            }
        }
        return toAjax(true);
    }

    /**
     * 商户获取订单信息接口
     * @param orderNo
     * @return
     */
    @Log(title = "商户获取订单信息", businessType = BusinessType.STOREGETORDERINFO)
    @PostMapping("/storeGetOrderInfo")
    public JR storeGetOrderInfo(String orderNo) {
        if(StringUtils.isEmpty(orderNo)){
            return JR.ok();
        }
        try{
            SysOrder sysOrder = sysOrderService.getInfoByStoreOrderNo(orderNo);
            if(sysOrder == null){
                logger.info("商户订单号不存在");
                return JR.build(500,"商户订单号不存在",500);
            }
            Map map = new HashMap();
            map.put("status",sysOrder.getSysOrderStatus()); // 0=等待中 1=充值中 2=充值成功 3=取消充值 4=渠道充值失败
            map.put("orderNo",sysOrder.getStoreOrderNo()); //商户订单号
            map.put("spOrderNo",sysOrder.getSysOrderNo()); //平台订单号
            map.put("createTime",sysOrder.getStoreOrderTime()); //订单创建时间
            map.put("finishTime",sysOrder.getOrderFinishTime()); //订单完成时间
            return JR.ok(map);
        }catch (Exception e){
            logger.info("doRecharge error:"+e.getMessage());
            return JR.build(500,"获取订单信息失败",500);
        }
    }


    /**
     * 查询订单状态（渠道方）
     * @param sysOrderNo
     * @return
     */
    @Log(title = "查询订单状态", businessType = BusinessType.GETCHANNELORDERINFO)
    @PostMapping("/getChannelOrderInfo")
    public JR getChannelOrderInfo(String sysOrderNo) {
        if(StringUtils.isEmpty(sysOrderNo)){
            return JR.ok();
        }
        try{
            SysOrder sysOrder = sysOrderService.getInfoBySysOrderNo(sysOrderNo);
            if(sysOrder == null){
                return JR.build(500,"订单号不存在",500);
            }
            if(sysOrder.getRealRechargePlat() == null){
                return JR.build(500,"渠道不存在,查单失败",500);
            }
           if(sysOrder.getRealRechargePlat() ==1){
                //盈华
               Map map = RechargeUtils.getYHOrder(sysOrderNo);
               if(map == null){
                   return JR.build(500,"盈华查单失败",500);
               }
               if(map.get("code")!= null && Integer.parseInt(map.get("code").toString()) ==200){
                   return JR.ok(map.get("data"));
               }else{
                   return JR.build(500,map.get("msg") != null ?String.valueOf(map.get("msg") ) :"欧飞查单失败",500);
               }

           }else if(sysOrder.getRealRechargePlat() ==2){
                //欧飞
               Map map = RechargeUtils.getOFOrderInfo(sysOrderNo);
               if(map == null || map.get("orderinfo") ==null){
                   return JR.build(500,"调用欧飞api查询订单异常",500);
               }
               return JR.ok(map.get("orderinfo"));
           }else{
               return JR.ok();
           }

        }catch (Exception e){
            logger.info("doRecharge error:"+e.getMessage());
            return JR.build(500,"获取订单信息失败",500);
        }
    }

}
